/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package InternetHax;

import java.io.InputStream;
import java.util.Vector;

/**
 *A collection of useful methods that don't really belong anywhere else
 * @author LoginError
 */
public class Toolbox {

    /**
     * Reads a text file from resources within the jar file 
     * returns the file as a string
     * NOTE: user must be an object in the same package as 
     * Toolbox due to the way getResourceAsStream works (or so i'm told).
     * 
     */
    public static String getStringFromFile(Object user, String filename) {
        StringBuffer sb = new StringBuffer();
        InputStream is = user.getClass().getResourceAsStream(filename);

        try {
            int chr, i = 0;
            // Read until the end of the stream      
            while ((chr = is.read()) != -1) {
                sb.append((char) chr);
            }
        } catch (Exception e) {
            System.out.println("Unable to create stream: " + filename);
            return null;
        }
        return sb.toString();
    }

    /**
     * Splits a string into several substrings based on a sparator 
     * @param original the original string to split
     * @param separator a string of aribtrary length serving as a delimeter
     * @return an arry of strings split at the separator
     */
    public static String[] splitString(String original, String separator) {
        Vector nodes = new Vector();

// Parse nodes into vector
        int index = original.indexOf(separator);
        while (index >= 0) {
            nodes.addElement(original.substring(0, index));
            original = original.substring(index + separator.length());
            index = original.indexOf(separator);
        }
// Get the last node
        nodes.addElement(original);

// Create splitted string array
        String[] result = new String[nodes.size()];
        if (nodes.size() > 0) {
            for (int loop = 0; loop < nodes.size(); loop++) {
                result[loop] = (String) nodes.elementAt(loop);
            }

        }

        return result;
    }

    /**
     * checks to see if the specified tile is currently on screen and thus can be seen by the player
     * @param the position of a tile as a Point2d, measured in Tiles
     * @return true if the tile is currently displayed on the screen, false otherwise
     */
    public static boolean canPlayerSeeTile(Point2d thetile) {
        return canPlayerSeeTile(thetile.x, thetile.y);
    }



    
    /**
     * checks to see if the specified tile is currently on screen and thus can be seen by the player
     * NOTE: This method needs to be changed, as there are cases where the camera is not centered on the player
     * @param x the x location of the tile to check
     * @param y the x location of the tile to check
     * @return true if the tile is currenly on the screen, false otherwise
     */
    public static boolean canPlayerSeeTile(int x, int y) {
        int numTilesx, numTilesy;
        numTilesx = (Gamestate.screenWidth / Constants.TILESIZE_IN_PIXELS) - 1;
        numTilesy = (Gamestate.screenHeight / Constants.TILESIZE_IN_PIXELS) - 1;

        Point2d playerpos = Gamestate.theHero.getTilePosition();

        //if the diferance is less than the number of tiles on screen then the player can see it
        if (Math.abs(x - playerpos.x) <= numTilesx && Math.abs(y - playerpos.y) <= numTilesy) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * Determines if a direction is diagonal
     * @param direction
     * @return
     */
    public static boolean isDiagonal(int direction) {
        return (direction > Constants.DIRECTION_RIGHT);
    }

    /**
     * Takes a direction as discribed in {@link Constants} and flips it vertiacally.
     * The main purpose of this function is to allow the numpad on a computer to better
     * emulate the numpad on a phone (which is flipped vertically)
     * @param direction the direction to flip
     * @return the direction after being flipped vertically;
     */
    public static int flipVertical(int direction)
    {
        switch (direction)
        {
            case Constants.DIRECTION_DOWN:
                return Constants.DIRECTION_UP;
            
            case Constants.DIRECTION_UP:
                return Constants.DIRECTION_DOWN;
            
            case Constants.DIRECTION_DOWN_LEFT:
                return Constants.DIRECTION_UP_LEFT;
            
            case Constants.DIRECTION_DOWN_RIGHT:
                return Constants.DIRECTION_UP_RIGHT;
            
            case Constants.DIRECTION_UP_RIGHT:
                return Constants.DIRECTION_DOWN_RIGHT;
            
            case Constants.DIRECTION_UP_LEFT:
                return Constants.DIRECTION_DOWN_LEFT;
                
            default:
                return direction;
        }
    }
    
    public static String directionToString(int direction)
    {
        
        switch (direction)
        {
            case Constants.DIRECTION_DOWN:
                return "down";
            
            case Constants.DIRECTION_UP:
                return "up";
            
            case Constants.DIRECTION_RIGHT:
                return "right";
            
            case Constants.DIRECTION_LEFT:
                return "left";
                
            case Constants.DIRECTION_DOWN_LEFT:
                return "down-left";
            
            case Constants.DIRECTION_DOWN_RIGHT:
                return "down-right";
            
            case Constants.DIRECTION_UP_RIGHT:
                return "up-right";
            
            case Constants.DIRECTION_UP_LEFT:
                return "up-left";
                
            case Constants.DIRECTION_CENTER:
                return "center";
                
            default:
                return "an invalid direction";
        }
        
    }
    
    public static void printDebug(String string)
    {
        if(Gamestate.printDebug)
            System.err.println(string);
    }

    
    public static void printDebug(String string,int indent)
    {
        String indentStr = "";
        
        for (int i = 0; i < indent; i++) {
            indentStr += "\t";
        }
        
        if(Gamestate.printDebug)
            System.err.println(indentStr+string);
    }

    /**
     * A very basic but fast pathfinder, returns the direction an actor should travel
     * from start to reach end. This does not take into account obstacles, other actors or
     * any external forces, it simply returns the direction that is the shortest
     * @param start a tile on the map specifying the location to start at
     * @param end   a tile on the map specifying the goal location
     * @return returns Constants.DIRECTION_RIGHT , LEFT, UP or DOWN
     */
    public static int directionToTile4(Point2d start, Point2d end) {
        int xdif = start.x - end.x;
        int ydif = start.y - end.y;

        //x is shorter than y
        if (Math.abs(xdif) > Math.abs(ydif)) {
            if (xdif < 0) {
                return Constants.DIRECTION_RIGHT;
            }
            else {
                return Constants.DIRECTION_LEFT;
            }
        }
        else {
            if (ydif < 0) {
                return Constants.DIRECTION_DOWN;
            }
            else {
                return Constants.DIRECTION_UP;
            }
        }

    }
}
